/*
 * @Description: 用户任务表单
 * @Author: DHL
 * @Date: 2022-10-12 10:32:12
 * @LastEditors: DHL
 * @LastEditTime: 2022-11-18 23:50:44
 */

import { defineComponent } from 'vue'
import { useBpmnStore } from '../../../../store/bpmn'
import { UserModel } from '/@/api/system/model/userModel'
import selectUser from '/@/pages/components/selectUser.vue'
import { assign, cloneDeep } from 'lodash-es'
import { arrayRemoveByPropertyValue } from '/@/utils/twUtils'
import { apiPostSearchList } from '/@/api/system/post'
import { PostModel } from '/@/api/system/model/postModel'
import { ApprovalRulesModel, TimeLimitRulesModel } from './../../../../model/approvalRulesModel'

export default defineComponent({
  name: 'UserTaskForm',
  components: { selectUser },
  setup(props, { emit, expose }) {
    //////////////////////////////////////////////////
    // 属性
    //////////////////////////////////////////////////
    const bpmnStore = useBpmnStore()

    const modelVisible = ref(false)

    const activeTabsName = ref('setUpApprover')

    const defaultState = {
      // 审批类型
      category: 'manualApproval',

      // 审批规则
      assignedRules: {
        type: 'specified', // 审批人类型
        optionalWay: null, // 发起人自选方式
        assigneeList: [] as Array<UserModel>, // 审批用户集合
        postId: null, // 岗位主键
        levelChecked: false, // 是否勾选同时不超过发起人向上的层级
        level: null // 同时不超过发起人向上的层级
      },

      // 多人审批时采用的审批方式
      multiInstanceRules: {
        approvalWay: 'parallel' // 多人审批时采用的审批方式
      },

      // 审批超时限制规则
      timeLimitRules: {} as TimeLimitRulesModel
    }

    const state = reactive<ApprovalRulesModel>(cloneDeep(defaultState))

    //////////////////////////////////////////////////
    // 初始化
    //////////////////////////////////////////////////

    /**
     * 打开弹框
     */
    function handleOpen() {
      modelVisible.value = true

      handleSearchPost()

      assign(state, cloneDeep(defaultState), bpmnStore.getApprovalRules)
    }

    /**
     * 关闭弹框
     */
    function handleClose() {
      modelVisible.value = false
    }

    //////////////////////////////////////////////////
    // 审批规则配置
    //////////////////////////////////////////////////

    /**
     * 设置审批人规则
     * specified：指定成员
     * optional：发起人自选
     * continuousMultistage：连续多级主管
     * departmentHead：部门主管
     * supervisor：直属主管
     * role：角色
     * initiator：发起人自己
     */
    function handleChangeRulesType(rulesType: string) {
      state.assignedRules = assign(cloneDeep(defaultState.assignedRules), {
        type: rulesType
      })

      switch (state.assignedRules.type) {
        case 'specified': //指定成员
          break

        case 'optional': //发起人自选
          break

        case 'continuousMultistage': //连续多级主管
          state.multiInstanceRules.approvalWay = 'sequential' // 依次审批
          break

        case 'supervisor': //直属主管
          state.multiInstanceRules.approvalWay = 'sequential' // 依次审批
          break

        case 'initiator': //发起人自己
          break

        default:
          break
      }
    }

    //////////////////////////////////////////////////
    // 多人审批方式
    //////////////////////////////////////////////////

    /**
     * 多实例对象
     */
    let multiLoopInstanceObject = null

    /**
     * 是否显示多人审批方式
     */
    const multiWayShow = computed(() => {
      // 审批用户大于1触发多人审批配置
      if (state.assignedRules.assigneeList && state.assignedRules.assigneeList.length > 1) {
        return true
      }

      // 发起人自选,自选多个人
      if (state.assignedRules.type === 'optional' && state.assignedRules.optionalWay === 'more') {
        return true
      }

      return false
    })

    /**
     * 构建多实例
     * @param isDel 是否删除多实例配置节点，默认不删除
     * @returns
     */
    function buildLoopCharacteristics(isDel = false) {
      if (isDel) {
        // 小于两个用户，不需要构建多实例
        bpmnStore.updateProperties({ loopCharacteristics: null })
        multiLoopInstanceObject = null
        return
      }

      if (state.multiInstanceRules.approvalWay === 'sequential') {
        // 依次审批
        multiLoopInstanceObject = bpmnStore.createModdleElement(
          'bpmn:MultiInstanceLoopCharacteristics',
          {
            isSequential: true
          }
        )
      } else if (state.multiInstanceRules.approvalWay === 'parallel') {
        // 会签（须所有审批人同意）
        multiLoopInstanceObject = bpmnStore.createModdleElement(
          'bpmn:MultiInstanceLoopCharacteristics'
        )
      } else if (state.multiInstanceRules.approvalWay === 'orSign') {
        // 或签（一名审批人同意或拒绝即可）
      }

      // 创建多实例元素
      bpmnStore.updateProperties({
        loopCharacteristics: multiLoopInstanceObject
      })

      // 设置集合
      updateLoopCollection()

      // 循环基数
      updateLoopCardinality()
    }

    /**
     * 设置集合（collection）
     */
    function updateLoopCollection() {
      // 设置集合变量
      bpmnStore.updateModdleProperties(multiLoopInstanceObject, {
        collection: `assigneeList_${bpmnStore.activatedElementId}`,
        elementVariable: 'assignee'
      })
    }

    /**
     * 循环基数
     */
    function updateLoopCardinality() {
      // let loopCardinality = bpmnStore.createModdleElement('bpmn:FormalExpression', {
      //   body: ''
      // })

      // bpmnStore.updateModdleProperties(multiLoopInstanceObject, { loopCardinality })

      // 完成条件
      updateLoopCondition()
    }

    /**
     * 完成条件
     */
    function updateLoopCondition() {
      let completionCondition = null

      // 完成的条件
      let condition = ''

      // 或签
      if (state.multiInstanceRules.approvalWay === 'orSign') {
        condition = `\${nrOfCompletedInstances>=1}`
      } else {
        condition = '${nrOfCompletedInstances==nrOfInstances}'
      }

      if (multiLoopInstanceObject) {
        completionCondition = bpmnStore.createModdleElement('bpmn:FormalExpression', {
          body: condition
        })

        bpmnStore.updateModdleProperties(multiLoopInstanceObject, {
          completionCondition
        })
      }
    }

    //////////////////////////////////////////////////
    // 审批人为空
    //////////////////////////////////////////////////

    /**
     * 审批人为空是否显示
     */
    const userNullShow = computed(() => {
      return false
    })

    //////////////////////////////////////////////////
    // 构建审批规则
    //////////////////////////////////////////////////
    /**
     * 构建审批规则
     */
    function buildRules() {
      handleSpecified()
      handleOptional()
      handleContinuousMultistage()
      handleSupervisor()
      handleInitiator()
    }

    /**
     * 指定成员
     */
    function handleSpecified() {
      if (state.assignedRules.type === 'specified') {
        if (state.assignedRules.assigneeList.length > 1) {
          bpmnStore.updateProperties({ assignee: '${assignee}' })
          // 构建多实例
          buildLoopCharacteristics()
        } else if (state.assignedRules.assigneeList.length === 1) {
          const userId = state.assignedRules.assigneeList[0].id
          bpmnStore.updateProperties({ assignee: userId })
          // 构建多实例
          buildLoopCharacteristics(true)
        } else {
          bpmnStore.updateProperties({ assignee: null })
          // 构建多实例
          buildLoopCharacteristics(true)
        }
      }
    }

    /**
     * 发起人自选
     */
    function handleOptional() {
      if (state.assignedRules.type === 'optional') {
        if (state.assignedRules.optionalWay === 'more') {
          bpmnStore.updateProperties({ assignee: '${assignee}' })
          // 构建多实例
          buildLoopCharacteristics()
        } else {
          // 删除多实例
          buildLoopCharacteristics(true)
        }
      }
    }

    /**
     * 连续多级主管
     */
    function handleContinuousMultistage() {
      if (state.assignedRules.type === 'continuousMultistage') {
        bpmnStore.updateProperties({ assignee: '${assignee}' })
        // 构建多实例
        buildLoopCharacteristics()
      }
    }

    /**
     * 直属主管
     */
    function handleSupervisor() {
      if (state.assignedRules.type === 'supervisor') {
        if (state.assignedRules.level === '1') {
          bpmnStore.updateProperties({ assignee: '${assignee}' })

          // 删除多实例
          buildLoopCharacteristics(true)
        } else {
          bpmnStore.updateProperties({ assignee: '${assignee}' })
          // 构建多实例
          buildLoopCharacteristics()
        }
      }
    }

    /**
     * 发起人自己
     */
    function handleInitiator() {
      if (state.assignedRules.type === 'initiator') {
        bpmnStore.updateProperties({ assignee: '${initiator}' })
        // 删除多实例
        buildLoopCharacteristics(true)
      }
    }

    //////////////////////////////////////////////////
    // 提交配置
    //////////////////////////////////////////////////
    /**
     * 提交审批人设置
     */
    function handleSubmit() {
      // 设置审批规则
      bpmnStore.setApprovalRules(state)

      // 构建审批规则
      buildRules()

      // 关闭
      handleClose()
    }

    //////////////////////////////////////////////////
    // 选择用户
    //////////////////////////////////////////////////

    /**
     * 用户选择
     */
    const selectUserRef = ref()

    /**
     * 弹出选择用户
     */
    function handleSelectUserOpen() {
      selectUserRef.value.handleOpen()
    }

    /**
     * 选择用户确认
     * @param userList
     */
    function handleSubmitSelectUser(userList) {
      state.assignedRules.assigneeList = userList
    }

    /**
     * 清空选择用户
     */
    function handleClearUser() {
      state.assignedRules.assigneeList = []
    }

    /**
     * 删除用户
     * @param user
     */
    function handleDeleteUser(user) {
      arrayRemoveByPropertyValue(state.assignedRules.assigneeList, 'id', user.id)
    }

    //////////////////////////////////////////////////
    // 岗位
    //////////////////////////////////////////////////
    const postList = ref([] as Array<PostModel>)

    /**
     * 查询岗位集合
     */
    function handleSearchPost() {
      apiPostSearchList({}).then((result) => {
        if (result?.success) {
          postList.value = result.data
        }
      })
    }

    //////////////////////////////////////////////////
    // 生命周期
    //////////////////////////////////////////////////

    /**
     * 暴露函数
     */
    expose({ handleOpen })

    return {
      modelVisible,
      activeTabsName,
      state,
      multiWayShow,
      handleClose,
      handleChangeRulesType,
      handleSubmit,
      selectUserRef,
      handleSelectUserOpen,
      handleSubmitSelectUser,
      handleClearUser,
      handleDeleteUser,
      postList,
      userNullShow
    }
  }
})
